package org.javahispano.javacup.tacticas_aceptadas.Arturo8a.AlianzaLima;

import org.javahispano.javacup.modelo.Constantes;
import org.javahispano.javacup.modelo.Posicion;
import org.javahispano.javacup.modelo.SituacionPartido;

/**
 *
 * @author Administrador
 */
public class Balon {
    public double balonDx;
    public double balonDy;
    public double balonDz;
    public double angulo;
    public Posicion ultimaPosicion;
    public double alturaBalon;
    public boolean rebote;
    public SituacionPartido sp;
    public static Posicion antPos;

    public Balon(){
        balonDx = 0;
        balonDy = 0;
        balonDz = 0;
        angulo = 0;
        alturaBalon = 0;
        ultimaPosicion = new Posicion(0,0);
    }

    public boolean esGol(double x, double y){
        return (x<19.5 && y>=-52.5 && x>-19.5) || (x>-19.5 && y>=-52.5 && x<19.5);
    }

    public Posicion getPosicionActual(){
        return sp.balon();
    }

    public Posicion[] getTrayectoriaDisparo(Posicion jugador,Posicion balon,Posicion destino, double fuerza){
        Posicion[] trayectoria = new Posicion[30];
		double x = balon.getX();
		double y = balon.getY();
		trayectoria[0] = new Posicion(x, y);
        double vel = Constantes.getVelocidadRemate(fuerza);
        double balonDx = Math.cos(angulo) * vel;
        double balonDy = Math.sin(angulo) * vel;

        for(int i=1;i<trayectoria.length;i++){
        if (alturaBalon==0) {
            balon = new Posicion((balon.getX()+balonDx),(balon.getY()+balonDy));
            balonDx = balonDx * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
            balonDy = balonDy * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
        } else {
            balonDx = balonDx * Constantes.FACTOR_DISMINUCION_VEL_BALON_AIRE;
            balonDy = balonDy * Constantes.FACTOR_DISMINUCION_VEL_BALON_AIRE;
        }
        trayectoria[i] =new Posicion(balon.getX(),balon.getY());
        }

		return trayectoria;
    }

    public Posicion[] getTrayectoria(){
        Posicion[] trayectoria = new Posicion[10];
        Posicion balon = sp.balon();
        //System.out.println("BALON INTERNO : "+sp.balon().getX()+","+sp.balon().getY());
        double balonDx = this.balonDx;
        double balonDy = this.balonDy;
        
        for(int i=0;i<trayectoria.length;i++){
        if (sp.alturaBalon()==0) {
            balon = new Posicion((balon.getX()+balonDx),(balon.getY()+balonDy));
            balonDx = balonDx * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
            balonDy = balonDy * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
        } else {
            balonDx = balonDx * Constantes.FACTOR_DISMINUCION_VEL_BALON_AIRE;
            balonDy = balonDy * Constantes.FACTOR_DISMINUCION_VEL_BALON_AIRE;
        }
        trayectoria[i] =new Posicion(balon.getX(),balon.getY());
        }
        return trayectoria;
    }


    public void actualizarBalon(){
        Posicion balon = sp.balon();
        
        this.angulo = sp.balon().angulo(ultimaPosicion);
        if(balon.getX()==34 || balon.getX()==-34
                || balon.getY()==52.5 || balon.getY()==-52.5
                || (balon.getX()==0 && balon.getY()==0)
                || ((balon.getX()==9.16 || balon.getX()==-9.16) && balon.getY()==-47))
        {
            balonDx = 0;
            balonDy = 0;
            //System.out.println("El balon esta parado");
            this.angulo=0;
        }
        if(sp.alturaBalon()==0){
            this.balonDx = (sp.balon().getX()-ultimaPosicion.getX())*Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
            this.balonDy = (sp.balon().getY()-ultimaPosicion.getY())*Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;

        }else{
            this.balonDx = (sp.balon().getX()-ultimaPosicion.getX())*Constantes.FACTOR_DISMINUCION_VEL_BALON_AIRE;
            this.balonDy = (sp.balon().getY()-ultimaPosicion.getY())*Constantes.FACTOR_DISMINUCION_VEL_BALON_AIRE;
        }
        ultimaPosicion = sp.balon();

    }

    public Posicion getPosicionFinal(){
        boolean suelo = false;
        Posicion balon = sp.balon();

        for(int i=0;i<100;i++){
        if (!suelo && (alturaBalon==0) && (balonDz>=0) && balonDz<Constantes.G * 3) {
            suelo = true;
        }
        if (suelo) {
            balon = balon.moverPosicion(balonDx, balonDy);
            balonDx = balonDx * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
            balonDy = balonDy * Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
        } else {
            alturaBalon = redondeaMultiplo(alturaBalon + balonDz, Constantes.G);
            balon = balon.moverPosicion(balonDx, balonDy);
            balonDz = redondeaMultiplo(balonDz - Constantes.G, Constantes.G);
            balonDx = balonDx * Constantes.FACTOR_DISMINUCION_VEL_BALON_AIRE;
            balonDy = balonDy * Constantes.FACTOR_DISMINUCION_VEL_BALON_AIRE;
            if (alturaBalon == 0) {
                balonDz = (-balonDz - Constantes.G) * Constantes.FACTOR_DISMINUCION_ALTURA_BALON_REBOTE;
                balonDz = redondeaMultiplo(balonDz, Constantes.G);
                rebote = true;
            }
        }
        if(balonDx==0d && balonDy==0d && balonDz==0d) break;
        }
        return new Posicion(balonDx,balonDy);

    }

    public double redondeaMultiplo(double valor, double divisor) {
        return Math.round(valor / divisor) * divisor;
    }

    public void setSP(SituacionPartido sp){
        this.sp = sp;
    }

    public boolean estoyMasCercaDeBola(){
        int dev1[]=getInfoMasCercano(sp.misJugadores(), sp.balon(), null, false);
        int dev2[]=getInfoMasCercano(sp.rivales(), sp.balon()   , null, false);
        return dev1[1]<dev2[1];
    }

    public int getMasCercanoDeBola(){
        int dev1[]=getInfoMasCercano(sp.misJugadores(), sp.balon(), null, false);
        //System.out.println(dev1[0]);
        return dev1[0];
    }

    public int getSiguienteJugador(int nJugador){
        int nExc[]={nJugador};
        Posicion[] misJugadores = sp.misJugadores();
        int dev1[]=getInfoMasCercano(misJugadores,misJugadores[nJugador],nExc, true);
        return dev1[0];
    }

    public int getContrarioMasCerca(int nJugador){
        Posicion[] rivales = sp.rivales();
        Posicion[] misJugadores = sp.misJugadores();
        int dev1[]=getInfoMasCercano(rivales,misJugadores[nJugador],null,false);
        return dev1[0];
    }

    public int getContrarioMasCerca(double x, double y){
        Posicion p=new Posicion();
        p.setPosicion(x,y);
        Posicion[] rivales = sp.rivales();
        int dev1[]=getInfoMasCercano(rivales,p,null,false);
        return dev1[0];
    }

    public int getMiJugadorMasCerca(double x, double y){
        Posicion p=new Posicion();
        p.setPosicion(x,y);
        Posicion[] misJugadores = sp.misJugadores();
        int dev1[]=getInfoMasCercano(misJugadores,p,null,false);
        return dev1[0];
    }
    public int[] getInfoMasCercano(Posicion[] lista, Posicion punto, int excluir[], boolean soloDelante){
        int dev[]={-1,999};
        int nDis;
        for (int n=0;n<lista.length;n++){
            if (!estaEnVector(excluir, n)){
                if (!soloDelante || lista[n].getX()>punto.getX()){
                    nDis=(int)Herramientas.distancia2Puntos(new Posicion(lista[n].getX(), lista[n].getY()), new Posicion(punto.getX(), punto.getY()));
                    if (nDis<dev[1]){
                        dev[0]=n;
                        dev[1]=nDis;
                    }
                }
            }
        }
        return dev;
    }
    private static boolean estaEnVector(int vector[], int num){
        if (vector==null) return false;
        for (int n=0;n<vector.length;n++)
            if (vector[n]==num)
                return true;
        return false;
    }

    public int rivalesEnRadio(int radio, int jugador){
        Posicion[] misJugadores = sp.misJugadores();
        Posicion[] misRivales = sp.rivales();
        int rivales = 0;
        double xMi = misJugadores[jugador].getX();
        double yMi = misJugadores[jugador].getY();
        for(int i=0;i<misRivales.length;i++){
            double xRi = misRivales[i].getX();
            double yRi = misRivales[i].getY();

            double distancia = Herramientas.distancia2Puntos(new Posicion(xMi,yMi), new Posicion(xRi,yRi));
            if (distancia<radio) rivales++;

        }
        return rivales;
    }

    public int getJugadorLibreMasCercano(int yo){
        int indice = 0;
        Posicion[] misJugadores = sp.misJugadores();
        double xMi = misJugadores[yo].getX();
        double yMi = misJugadores[yo].getX();
        double minDist = 1000;
        for(int i=1;i<misJugadores.length;i++){
            if(i!=yo){
                int rivales = rivalesEnRadio(2, i);
                if(rivales==0){
                    double dist = Herramientas.distancia2Puntos(new Posicion(xMi,yMi), new Posicion(misJugadores[i].getX(),misJugadores[i].getY()));
                    if (dist<minDist){
                        indice = i;
                        minDist = dist;
                    }
                }
            }
        }
        return indice;
    }

    public int[] getTresRivalesMasCercanos(){
        Posicion[] misRivales = sp.rivales();
        double[][] cercanos = new double[11][11];
        for(int j=0;j<misRivales.length;j++){
            double dist = Herramientas.distancia2Puntos(new Posicion(misRivales[j].getX(),misRivales[j].getY()), Constantes.centroArcoInf);
            
            cercanos[j][0] = j;
            cercanos[j][1] = dist;
        }
        for(int i=cercanos.length-1;i>0;i--){
            for(int j=0;j<i;j++){
                if(cercanos[j][1]>cercanos[j+1][1]){
                    double tmp = cercanos[j+1][1];
                    double tmp2 = cercanos[j+1][0];
                    cercanos[j+1][1]=cercanos[j][1];
                    cercanos[j+1][0]=cercanos[j][0];
                    cercanos[j][1] = tmp;
                    cercanos[j][0] = tmp2;

                }
            }
        }
        int[] indices = new int[3];
        for(int i=0;i<=2;i++){
            indices[i] = (int)cercanos[i][0];
            //System.out.println("Rival No "+(i+1)+" "+indices[i]);
        }
        return indices;
    }

    

    
   
    public int[][] setMarcajes(){
        int[][] marcajes = new int[3][3];
        int[] estanMarcando = new int[4];
        int[] amarcar = getTresRivalesMasCercanos();
        Posicion[] misJugadores = sp.misJugadores();
        Posicion[] misRivales = sp.rivales();
        int d=0;
        for(int k=0;k<amarcar.length;k++){
            double dist1 = Herramientas.distancia2Puntos(misJugadores[1], misRivales[k]);
            double dist2 = Herramientas.distancia2Puntos(misJugadores[2], misRivales[k]);
            double dist3 = Herramientas.distancia2Puntos(misJugadores[3], misRivales[k]);
//            System.out.println("Rival : "+amarcar[k]);
//            System.out.println("Primera Distancia : "+dist1);
//            System.out.println("Segunda Distancia : "+dist2);
//            System.out.println("Ter            System.out.printlncera Distancia : "+dist3);
            double[][] distancias = new double[][]{{1,dist1},{2,dist2},{3,dist3}};
           for(int i=distancias.length-1;i>0;i--){
                    for(int j=0;j<i;j++){
                        if(distancias[j][1]>distancias[j+1][1]){
                            double tmp = distancias[j+1][1];
                            double tmp2 = distancias[j+1][0];
                            distancias[j+1][1]=distancias[j][1];
                            distancias[j+1][0]=distancias[j][0];
                            distancias[j][1] = tmp;
                            distancias[j][0] = tmp2;

                        }
                    }
            }
            for(int i=0;i<distancias.length;i++){
                //System.out.println(" Indice : "+distancias[i][0]+" Distancia :"+distancias[i][1]);
            }
            int[] losindices = new int[]{(int)distancias[0][0],(int)distancias[1][0],(int)distancias[2][0]};
//            System.out.println(" 1er Indice : "+losindices[0]);
//            System.out.println(" 2do Indice : "+losindices[1]);
//            System.out.println(" 3er Indice : "+losindices[2]);
//            System.out.println(" M 1 :"+estanMarcando[0]);
//            System.out.println(" M  2:"+estanMarcando[1]);
//            System.out.println(" M   3:"+estanMarcando[2]);

            if(!estaEnVector(estanMarcando,losindices[0])){
                //System.out.println("Jugador "+(losindices[0])+" No esta marcando");
                marcajes[d][0]=losindices[0];
                //System.out.println("Seteado marcaje en posicion "+d+" el jugador "+losindices[0]);
                marcajes[d][1]=amarcar[k];
                //System.out.println("Se debe marcar al jugador "+amarcar[k]);
                estanMarcando[d]=losindices[0];
                //System.out.println("Estan marcando en posicion "+d+" el jugador "+losindices[0]);
                //for(int i=0;i<marcajes.length;i++){
                //System.out.println("Jugador No "+marcajes[i][0]+" Marca a Rival No: "+marcajes[i][1]);
                //}
            }
            else if(!estaEnVector(estanMarcando,losindices[1])){
                //System.out.println("Jugador "+(losindices[1])+" No esta marcando");
                marcajes[d][0]=losindices[1];
                marcajes[d][1]=amarcar[k];
                estanMarcando[d]=losindices[1];
                //for(int i=0;i<marcajes.length;i++){
                //System.out.println("Jugador No "+marcajes[i][0]+" Marca a Rival No: "+marcajes[i][1]);
                //}
            }
            else if(!estaEnVector(estanMarcando,losindices[2])){
                //System.out.println("Jugador "+(losindices[2])+" No esta marcando");
                marcajes[d][0]=losindices[2];
                marcajes[d][1]=amarcar[k];
                estanMarcando[d]=losindices[2];
                //for(int i=0;i<marcajes.length;i++){
                //System.out.println("Jugador No "+marcajes[i][0]+" Marca a Rival No: "+marcajes[i][1]);
                //}
            }
            d++;
        }
//        System.out.println("Finalmente : ");
//        System.out.println(" M :"+estanMarcando[0]);
//        System.out.println(" M  :"+estanMarcando[1]);
//        System.out.println(" M   :"+estanMarcando[2]);
        for(int i=0;i<marcajes.length;i++){
            //System.out.println("Jugador No "+marcajes[i][0]+" Marca a Rival No: "+marcajes[i][1]);
        }
        return marcajes;
    }

}
